package com.example.graphmovieapp.controller;

import com.example.graphmovieapp.domain.entity.Movie;
import com.example.graphmovieapp.domain.entity.Person;
import com.example.graphmovieapp.service.MovieService;
import com.example.graphmovieapp.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;

import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Optional;

/**
 * MovieController类，提供电影相关的REST API端点
 * 
 * @author GraphMovieApp
 * @version 1.0
 */
@RestController
@RequestMapping("/api/movies")
public class MovieController {

    private final MovieService movieService;
    private final PersonService personService;

    /**
     * 构造函数，注入Service依赖
     * 
     * @param movieService 电影服务
     * @param personService 人物服务
     */
    @Autowired
    public MovieController(MovieService movieService, PersonService personService) {
        this.movieService = movieService;
        this.personService = personService;
    }

    /**
     * 创建电影
     * 
     * @param movie 要创建的电影
     * @return 创建后的电影
     */
    @PostMapping
    public ResponseEntity<Movie> createMovie(@Valid @RequestBody Movie movie) {
        try {
            Movie savedMovie = movieService.saveMovie(movie);
            return new ResponseEntity<>(savedMovie, HttpStatus.CREATED);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 根据ID获取电影
     * 
     * @param id 电影ID
     * @return 匹配的电影
     */
    @GetMapping("/{id}")
    public ResponseEntity<Movie> getMovieById(@PathVariable Long id) {
        try {
            Optional<Movie> movie = movieService.findMovieById(id);
            return movie.map(value -> new ResponseEntity<>(value, HttpStatus.OK))
                    .orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 获取所有电影
     * 
     * @return 所有电影列表
     */
    @GetMapping
    public ResponseEntity<List<Movie>> getAllMovies() {
        List<Movie> movies = movieService.findAllMovies();
        return new ResponseEntity<>(movies, HttpStatus.OK);
    }

    /**
     * 删除电影
     * 
     * @param id 电影ID
     * @return 操作结果
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteMovie(@PathVariable Long id) {
        try {
            movieService.deleteMovie(id);
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 根据标题获取电影
     * 
     * @param title 电影标题
     * @return 匹配的电影
     */
    @GetMapping("/by-title")
    public ResponseEntity<Movie> getMovieByTitle(@RequestParam String title) {
        try {
            Optional<Movie> movie = movieService.findMovieByTitle(title);
            return movie.map(value -> new ResponseEntity<>(value, HttpStatus.OK))
                    .orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 根据发行年份获取电影
     * 
     * @param released 发行年份
     * @return 匹配的电影列表
     */
    @GetMapping("/by-released")
    public ResponseEntity<List<Movie>> getMoviesByReleased(@RequestParam Integer released) {
        try {
            List<Movie> movies = movieService.findMoviesByReleased(released);
            return new ResponseEntity<>(movies, HttpStatus.OK);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 标题模糊查询（分页）
     * 
     * @param title 标题关键字
     * @param page 页码（从0开始）
     * @param size 每页大小
     * @return 分页的电影列表
     */
    @GetMapping("/search")
    public ResponseEntity<Page<Movie>> searchMoviesByTitle(
            @RequestParam String title,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        try {
            Pageable pageable = PageRequest.of(page, size);
            Page<Movie> movies = movieService.findMoviesByTitleContaining(title, pageable);
            return new ResponseEntity<>(movies, HttpStatus.OK);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 根据年份范围获取电影
     * 
     * @param start 起始年份
     * @param end 结束年份
     * @return 在指定年份范围内的电影列表
     */
    @GetMapping("/by-year-range")
    public ResponseEntity<List<Movie>> getMoviesByYearRange(
            @RequestParam Integer start,
            @RequestParam Integer end) {
        try {
            List<Movie> movies = movieService.findMoviesByReleasedBetween(start, end);
            return new ResponseEntity<>(movies, HttpStatus.OK);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 获取电影的演员
     * 
     * @param id 电影ID
     * @return 该电影的演员列表
     */
    @GetMapping("/{id}/actors")
    public ResponseEntity<List<Person>> getActorsInMovie(@PathVariable Long id) {
        try {
            Optional<Movie> movieOpt = movieService.findMovieById(id);
            if (!movieOpt.isPresent()) {
                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
            }
            
            List<Person> actors = personService.findActorsInMovie(movieOpt.get().getTitle());
            return new ResponseEntity<>(actors, HttpStatus.OK);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 获取电影的导演
     * 
     * @param id 电影ID
     * @return 该电影的导演列表
     */
    @GetMapping("/{id}/directors")
    public ResponseEntity<List<Person>> getDirectorsOfMovie(@PathVariable Long id) {
        try {
            Optional<Movie> movieOpt = movieService.findMovieById(id);
            if (!movieOpt.isPresent()) {
                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
            }
            
            List<Person> directors = personService.findDirectorsOfMovie(movieOpt.get().getTitle());
            return new ResponseEntity<>(directors, HttpStatus.OK);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 获取演员参演电影数量
     * 
     * @param personName 演员姓名
     * @return 该演员参演的电影数量
     */
    @GetMapping("/count-acted-by/{personName}")
    public ResponseEntity<Long> countMoviesActedByPerson(@PathVariable String personName) {
        try {
            Long count = movieService.countMoviesActedByPerson(personName);
            return new ResponseEntity<>(count, HttpStatus.OK);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 获取导演执导电影数量
     * 
     * @param personName 导演姓名
     * @return 该导演执导的电影数量
     */
    @GetMapping("/count-directed-by/{personName}")
    public ResponseEntity<Long> countMoviesDirectedByPerson(@PathVariable String personName) {
        try {
            Long count = movieService.countMoviesDirectedByPerson(personName);
            return new ResponseEntity<>(count, HttpStatus.OK);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 获取同时担任演员和导演的电影
     * 
     * @param personName 人物姓名
     * @return 该人物既参演又执导的电影列表
     */
    @GetMapping("/acted-and-directed-by/{personName}")
    public ResponseEntity<List<Movie>> getMoviesActedAndDirectedByPerson(@PathVariable String personName) {
        try {
            List<Movie> movies = movieService.findMoviesActedAndDirectedByPerson(personName);
            return new ResponseEntity<>(movies, HttpStatus.OK);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 获取合作演员
     * 
     * @param personName 演员姓名
     * @return 与该演员合作过的其他演员列表
     */
    @GetMapping("/co-actors/{personName}")
    public ResponseEntity<List<Person>> getCoActors(@PathVariable String personName) {
        try {
            List<Person> coActors = movieService.findCoActors(personName);
            return new ResponseEntity<>(coActors, HttpStatus.OK);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 创建电影并添加演员和导演
     * 
     * @param request 包含电影信息、演员姓名列表和导演姓名列表的请求体
     * @return 创建的电影
     */
    @PostMapping("/create-with-cast")
    public ResponseEntity<Movie> createMovieWithCast(@RequestBody Map<String, Object> request) {
        try {
            // 从请求体中提取电影信息
            Object movieDataObj = request.get("movie");
            if (movieDataObj == null) {
                return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
            }
            
            Map<String, Object> movieData = (Map<String, Object>) movieDataObj;
            Movie movie = new Movie();
            
            if (movieData.containsKey("title")) {
                movie.setTitle((String) movieData.get("title"));
            }
            
            if (movieData.containsKey("released")) {
                Integer released = (Integer) movieData.get("released");
                movie.setReleased(released);
            }
            
            // 提取演员姓名列表
            @SuppressWarnings("unchecked")
            List<String> actorNames = (List<String>) request.get("actorNames");
            
            // 提取导演姓名列表
            @SuppressWarnings("unchecked")
            List<String> directorNames = (List<String>) request.get("directorNames");
            
            // 创建电影并添加演员和导演
            Movie savedMovie = movieService.createMovieWithActorsAndDirectors(movie, actorNames, directorNames);
            
            return new ResponseEntity<>(savedMovie, HttpStatus.CREATED);
        } catch (ClassCastException | NullPointerException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        } catch (Exception e) {
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}